/*
 *   Copyright 2012, Thomas Kerber
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package milk.jpatch.classLevel;

import milk.jpatch.CPoolMap;
import milk.jpatch.Patch;

import org.apache.bcel.classfile.Field;

import java.util.ArrayList;
import java.util.List;

/**
 * Denotes a patch to a field.
 * @author Thomas Kerber
 * @version 1.0.0
 */
public abstract class FieldPatch implements Patch<List<Field>>{
    
    private static final long serialVersionUID = -8106940465706875870L;
    
    /**
     * The name of the field to patch.
     */
    protected final String name;
    
    /**
     * Creates.
     * @param name The field's name.
     */
    protected FieldPatch(String name){
        this.name = name;
    }
    
    /**
     * 
     * @return The name of the field patched.
     */
    public String getName(){
        return name;
    }
    
    @Override
    public List<Field> patch(List<Field> fields, CPoolMap map){
        fields = new ArrayList<Field>(fields);
        // Find preexisting field.
        for(int i = 0; i < fields.size(); i++){
            if(fields.get(i).getName().equals(name)){
                Field newField = patch(fields.get(i), map);
                if(newField == null)
                    fields.remove(i);
                else
                    fields.set(i, newField);
                return fields;
            }
        }
        // No preexisting field found.
        Field newField = patch((Field)null, map);
        if(newField != null)
            fields.add(newField);
        return fields;
    }
    
    /**
     * Patches the relevant field.
     * @param f The field to patch (if none exists, this may be null).
     * @param map The cpool map.
     * @return
     */
    public abstract Field patch(Field f, CPoolMap map);
    
}
